iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
Mobile Development

新手向Android&Kotlin學習紀錄30天系列 第 18

第18天 kotlin小學堂(7) : Function 函數

  • 分享至 

  • xImage
  •  

函數在程式中是很重要的一部分,用來完成特定任務、並且可以重複使用的程式碼區塊。基本上程式就是一系列的函數組成來完成一個比較複雜的任務。
其實前面一直使用的println()就是Kotlin標準庫準備好的函數。
我們也可以自訂函數,比如:需不需要傳入參數,還有完成任務後要不要返回資料供其他地方使用。

Function 結構

以這個add function為例,說明函數的組成:

private fun add(a :Int, b:Int):Int{
    return a+b
}
  • private : 可見性修飾符,沒有特別註明的話,是預設public。
  • fun : 函數宣告關鍵字
  • add : 函數名,採小駝峰命名,能準確表達這函數的任務為佳。
  • ():指定參數的地方,多個參數時,以逗點隔開,參數必須標明資料類別。呼叫此function時就必須依據需求傳入資料雷行符合的參數。
  • :Int : 返回值類型,很多函數都會返回值給呼叫者,如沒有寫明的話會是「:Unit」(此時return可省略不寫),如下例沒有標明返回類型:
    private fun foo(a:Int, b:Int){
    /*一些執行的任務*/
    return Unit//可選擇寫或不寫,一般都會省略
    }
    
  • {} : 函數本體,上面介紹的合起來private fun add(a :Int, b:Int):Int函數標頭。大括號{}為函數本體,是執行任務的地方,若需要返回資料的話,還會有相關語句指定回傳哪一些資料。

函數作用域

在函數本體{}中,變數的宣告、定義都在這裡完成,這個變數就只活在這個函數本體{}中,出了這個花括號,其他地方並不能辨識這個變數。
以下面這個函數foo舉例,定義一個變數strLength,在foo function以外的地方是無法使用的:

像上例strLenght這類宣告在function裡面的變數就叫做區域變數,因為它只存在函數本體內,這函數執行完後就不復存在,所以作用域可以理解成區域變數的生命週期。對於函數的參數來說也是如此,一旦執行完畢,參數也就消失了。

豆知識 :常看到foo是什麼意思? 如果常常爬程式類的文章,常常會看見foo、bar...等詞用來當變數名或函數名,說法很多,但總結就是名稱不影響說明,所以懶得想變數或函數名字,通用的一個舉例用名稱。地位相當於課堂中的小明吧,我想。有興趣了解:Foobar維基百科

呼叫函數

宣告完函數、定義了他的任務並不會使函數去執行。我們需要呼叫他,就像少年漫畫,主角使出招式前必須大聲喊出招式名一樣,而反派也都會乖乖聽完(??)。我想要請不會喊出招式的鬼滅之刃的鬼妹妹Nezuko來示範:

Nezuko如大家所知,具備了戰鬥功能,並且會為了保護哥哥和人類與鬼戰鬥,就假設當被鬼攻擊的時候,Nezuko會依據剩餘血量(0~100)的多少來做出一些反應,沒有鬼攻擊的時候,就會躲回箱子睡覺恢復體力,血量hp以Int來表示,而是否遭受鬼攻擊就以Boolean值來表示:

fun fight(hp: Int, demonIsAttacking: Boolean): String {
    val fightStatus = when (hp) {
        in 101..Int.MAX_VALUE -> "禰豆子升級~~"
        in 70..100 -> if (demonIsAttacking) "禰豆子一般戰鬥" else "禰豆子躲箱子睡覺"
        in 40..69 -> if (demonIsAttacking) "禰豆子暴怒 再生速度upup" else "禰豆子躲箱子睡覺"
        in 10..39 -> if (demonIsAttacking) "禰豆子使出血鬼術「爆血」機率提升30%" else "禰豆子躲箱子睡覺"
        else -> if (demonIsAttacking) "禰豆子失去意識" else "禰豆子躲箱子睡覺"
    }
    
    return "$fightStatus (hp:$hp, demon is Attacking : $demonIsAttacking)"
}

定義好戰鬥功能後,就要使用他囉。
在需要戰鬥技能的地方呼叫fight function,並傳入引數(nezukoHp、demonIsAttacking)讓function可以完成任務,把fight返回的字串存入變數nezukoStatus並印出看看,試著更改 nezukoHp 和 demonIsAttacking 的值,看看禰豆子如何戰鬥吧。

fun main() {
    var nezukoHp = 100
    var demonIsAttacking = true
    
    val nezukoStatus = fight(nezukoHp, demonIsAttacking)   //函數也可以儲存在變數裡
    println(nezukoStatus)
    
    //或是: println(fight(nezukoHp, demonIsAttacking))
}

函數的定義表明需要兩個參數(paramenter)。呼叫時我們必須在括號()中傳入參數要求的資料,這種輸入資料名叫引數(arguement),為函數提供輸入資料叫傳入引數
(術語說明:技術上來說,參數是函數需要的東西,而引數是由函數呼叫者傳入,以滿足函數參數的要求。) 引自:Kotlin權威2.0

預設引數

我們可以預先為函數參數預設初始值引數,如預設每次禰豆子都是滿血戰鬥:

fun fight(hp: Int = 100, demonIsAttacking: Boolean): String {...}

呼叫時,若沒有特別指定hp值,預設就是100,那還需要傳入其他引數怎麼辦?直接指定參數名就好囉:

fight(demonIsAttacking = true)  //hp =100,demonIsAttacking = true

當然,全部參數都可以預設引數,呼叫時便不需要輸入引數。需要改變其中某些引數時,在呼叫時,指名輸入新的值就可以囉。

這就是函數基本的用法了,明天見。


上一篇
第17天 kotlin小學堂(6) 控制流程 : 跳脫字元
下一篇
第19天 Kotlin小學堂(8) : 函數類型、Lambda
系列文
新手向Android&Kotlin學習紀錄30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言